import {ListenDir} from "./types";
import {FSWatcher} from "vite/types/chokidar";
import chokidar from 'chokidar';
import * as Process from "process";
import {ViteDevServer} from "vite";
import * as fs from 'fs'


Process.on("beforeExit", (code) => {
  console.log('所有监听移除', code)
  FileListen.ListenDirs.forEach(i => {
    if (i.watcher) {
      i.watcher.close()
    }
  })
});

export class FileListen {
  static ListenDirs: ListenDir[] = []

  private static listenDirFilesDel(basePath: string, callBack: (filePahs: string[]) => void): FSWatcher {
    const fsWatcher = chokidar.watch(basePath) as FSWatcher
    fsWatcher.on('all', (event, path) => {
      if (event === 'unlink' || event === 'add') {
        callBack(FileListen.ListenDirs.find(i => i.path === basePath).files)
      }
    })
    return fsWatcher
  }

  static addDirListen(path, filePath, callBack: (filePahs: string[]) => void) {
    const listenDir = FileListen.ListenDirs.find(i => i.path === path);
    if (!listenDir) {
      FileListen.ListenDirs.push({
        path,
        files: [filePath],
        watcher: FileListen.listenDirFilesDel(path, callBack)
      })
    } else {
      const s = listenDir.files.find(i => i === filePath);
      if (!s) {
        listenDir.files.push(filePath)
      }
    }
  }

  static viteAddDirListen(basePath: string, id: string, server: ViteDevServer) {
    if (server) {
      FileListen.addDirListen(basePath, id, (filePahs) => {
        const moduleById = server.moduleGraph.getModuleById(id);
        // 让文件失效
        server.moduleGraph.invalidateModule(moduleById)
        // 主动更新文件
        server.ws.send({
          type: 'update',
          updates: [
            {
              path: moduleById.url, // 获取web url，不能用文件路径
              type: 'js-update',
              acceptedPath: moduleById.url,
              timestamp: Date.now(),
              explicitImportRequired: false,
            }
          ]
        })
        filePahs.forEach(i => {
          // const moduleById = server.moduleGraph.getModuleById(i);
          // server.moduleGraph.invalidateModule(moduleById)
        })
      })
    }
  }
}
